#ifndef _MACHINE_H_
#define _MACHINE_H_

/*
	class : Machine
	desc : Creates an interface for working with low level
	components whose access depends entirely on the system itself.
	The restrictions to the machine class depend on the architecture
	itself as a side note. This isn't an interface I can really implement
	in a normal way. Never use this class as is. First define
	a class that inherits from it and implement the virtual functions.
	and use that class instead
*/
template<typedef MachineType>
class Machine
{
	protected:
		//interface to set the Program counter
		virtual void setPC(unsigned int PROCESSOR_ID,
					void* address)=0;
		//get the program counter
		virtual void* getPC(unsigned int PROCESSOR_ID)=0;
		//sets the program stack
		virtual void* getStack(unsigned int PROCESSOR_ID,
					unsigned int & size)=0;
		//sets the stack
		virtual void setStack(unsigned int PROCESSOR_ID,
					void* address,	
					unsigned int size)=0;
		//sets the data space
		virtual void setDataSpace(void* address,
					 unsigned int size)=0;
		//gets the data space
		virtual void* getDataSpace(unsigned int & size)=0;
		//gets the value in a register
		virtual unsigned long int getReg(unsigned int PROCESSOR_ID,
				 unsigned char REGISTER_ID)=0;
		//sets a value in a register.
		virtual void setReg(unsigned int PROCESSOR_ID,
				 unsigned char REGISTER_ID,
				 unsigned long int value)=0;
	public: 
		//sets the program counter.
		static void setProgramCounter(unsigned int PROCESSOR_ID,
					void* address)
		{MachineType::setPC(PROCESSOR_ID, address);}
		//gets the program counter
		static void* getProgramCounter(unsigned int PROCESSOR_ID)
		{return MachineType::getPC(PROCESSOR_ID);}
		//gets the program stack.
		static void* getProgramStack(unsigned int PROCESSOR_ID,
					unsigned int & size)
		{return MachineType::getStack(PROCESSOR_ID, size);}
		//sets the program stack
		static void setProgramStack(unsigned int PROCESSOR_ID,
					void* address,	
					unsigned int size)
		{MachineType::setStack(PROCESSOR_ID, address, size);}
		//sets the program data space
		static void setProgramDataSpace(void* address,
					 unsigned int size)
		{MachineType::setDataSpace(address, size);}
		//get program data space
		static void* getProgramDataSpace(unsigned int & size)
		{return MachineType::getDataSpace(size);}
		//get the register.
		static unsigned long int getRegister(unsigned int PROCESSOR_ID,
				 unsigned char REGISTER_ID)
		{return MachineType::getReg(PROCESSOR_ID, REGISTER_ID);}
		//sets a register.
		static void setRegister(unsigned int PROCESSOR_ID,
				 unsigned char REGISTER_ID,
				 unsigned long int value)
		{MachineType::setReg(PROCESSOR_ID, REGISTER_ID, value);}
		
};



#endif
